﻿using System;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Threading.Tasks;
using DB.Core.Models;
using Furion;
using Furion.FriendlyException;
using Microsoft.AspNetCore.Mvc.Filters;
using PMBF.Core.Enums;
using SqlSugar;

namespace PMBF.Core.Handler
{
    public class UserApiAuthenticationActionFilterAttribute : ActionFilterAttribute
    {
        private readonly SqlSugarClient db;

        public UserApiAuthenticationActionFilterAttribute()
        {
            db = (SqlSugarClient)App.GetService<ISqlSugarClient>();
        }

        /// <summary>
        /// 其它参数可以通过参数传递
        /// [UserApiAuthenticationActionFilter(Roles = "001,002,999")]
        /// </summary>
        public string Roles { get; set; }

        /// <summary>
        /// 使用方式[UserApiAuthenticationActionFilter]
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            Microsoft.AspNetCore.Http.HttpRequest request = context.HttpContext.Request;
            string token = request.Headers["authorization"].ToString();

            string api = request.Path;

            #region 处理API

            string[] apilist = api.Split('/');

            if (apilist.Length > 4)
            {
                var newlist = apilist.Take(4).ToArray();
                api = newlist[0] + "/" + newlist[1] + "/" + newlist[2] + "/" + newlist[3] + "/";
            }
            #endregion

            string method = request.Method.ToLower();

            //生成token时定义变量名称
            var userid = App.User?.FindFirstValue("UserId");

            //and m.hideInMenu=0
            int rs = db.Queryable<User>("o")
                 .AddJoinInfo("UserGroup", "g", "o.ID= g.UserID", JoinType.Inner)
                 .AddJoinInfo("GroupMenu", "gm", "g.GroupID = gm.GroupID", JoinType.Inner)
                 .AddJoinInfo("menuRule", "m", "gm.MenuRuleID = m.ID and m.Api like'" + api + "%' and m.HttpMethod ='" + method.ToLower() + "'", JoinType.Inner)
                 .Where(o => o.ID.ToString() == userid)
                 .Count();

            return rs == 0 ? throw Oops.Oh(SystemErrorCodes.E0009) : base.OnActionExecutionAsync(context, next);
        }
    }
}
